#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
本地Web仪表板 - 连接虚拟机Redis服务
"""

from flask import Flask, jsonify, request, render_template
import redis
import json
import logging
from datetime import datetime, timedelta

app = Flask(__name__)

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 虚拟机服务配置
VM_CONFIG = {
    'redis_host': '192.168.88.130',  # 虚拟机IP
    'redis_port': 6379,
    'redis_db': 0,
    'redis_password': '123456',
    'spider_api_port': 5000
}

class RemoteDataManager:
    def __init__(self):
        self.redis_client = None
        self.connect_redis()

    def connect_redis(self):
        try:
            self.redis_client = redis.Redis(
                host=VM_CONFIG['redis_host'],
                port=VM_CONFIG['redis_port'],
                db=VM_CONFIG['redis_db'],
                password=VM_CONFIG['redis_password'],
                decode_responses=True,
                socket_timeout=10,
                socket_connect_timeout=10
            )
            self.redis_client.ping()
            logger.info("✓ 成功连接到虚拟机Redis服务")
        except Exception as e:
            logger.error(f"✗ 连接虚拟机Redis失败: {e}")
            self.redis_client = None

    def get_latest_prices(self, limit=50):
        if not self.redis_client:
            return []
        try:
            keys = self.redis_client.keys('cnhnb_price:*')
            if not keys:
                return []
            data_list = []
            for key in keys:
                try:
                    data = self.redis_client.get(key)
                    if data:
                        item = json.loads(data)
                        data_list.append(item)
                except Exception as e:
                    logger.warning(f"解析数据失败 {key}: {e}")
            data_list.sort(key=lambda x: x.get('timestamp', 0), reverse=True)
            seen = set()
            unique_data = []
            for item in data_list:
                uniq_key = (item.get('name'), item.get('price_value'), item.get('location'), item.get('date'))
                if uniq_key not in seen:
                    seen.add(uniq_key)
                    unique_data.append(item)
                if len(unique_data) >= limit:
                    break
            return unique_data
        except Exception as e:
            logger.error(f"获取价格数据失败: {e}")
            return []

    def get_system_status(self):
        status = {
            'redis_connected': False,
            'spider_running': False,
            'data_count': 0,
            'last_update': None
        }
        try:
            if self.redis_client:
                self.redis_client.ping()
                status['redis_connected'] = True
                keys = self.redis_client.keys('cnhnb_price:*')
                status['data_count'] = len(keys)
                if keys:
                    latest_key = max(keys, key=lambda k: self.redis_client.get(k))
                    latest_data = self.redis_client.get(latest_key)
                    if latest_data:
                        item = json.loads(latest_data)
                        status['last_update'] = item.get('crawl_timestamp')
                        if item.get('crawl_timestamp'):
                            try:
                                last_time = datetime.fromisoformat(item['crawl_timestamp'])
                                if datetime.now() - last_time < timedelta(minutes=1):
                                    status['spider_running'] = True
                            except Exception:
                                pass
        except Exception as e:
            logger.error(f"检查Redis状态失败: {e}")
        return status

data_manager = RemoteDataManager()

@app.route('/')
def index():
    return render_template('dashboard.html')

@app.route('/api/latest_prices')
def api_latest_prices():
    all_data = data_manager.get_latest_prices(limit=100000)
    return jsonify({
        'success': True,
        'data': all_data,
        'count': len(all_data),
        'timestamp': datetime.now().isoformat()
    })

@app.route('/api/system_status')
def api_system_status():
    status = data_manager.get_system_status()
    return jsonify({
        'success': True,
        'data': status,
        'timestamp': datetime.now().isoformat()
    })

@app.route('/api/health')
def health_check():
    redis_connected = data_manager.redis_client is not None
    try:
        if redis_connected:
            data_manager.redis_client.ping()
    except:
        redis_connected = False
    return jsonify({
        'success': True,
        'status': 'connected' if redis_connected else 'disconnected',
        'redis_status': 'connected' if redis_connected else 'disconnected',
        'timestamp': datetime.now().isoformat()
    })

@app.route('/api/statistics')
def api_statistics():
    all_data = data_manager.get_latest_prices(limit=100000)
    stats = {}
    recent_count_24h = 0
    now = datetime.now()

    for item in all_data:
        name = item.get('name')
        price = float(item.get('price_value') or 0)
        location = item.get('location')
        ts_str = item.get('crawl_timestamp')

        if not name or not price:
            continue

        if name not in stats:
            stats[name] = {
                'count': 0,
                'total_price': 0,
                'locations': set(),
                'max_price': price,
                'min_price': price
            }

        stat = stats[name]
        stat['count'] += 1
        stat['total_price'] += price
        stat['locations'].add(location)
        stat['max_price'] = max(stat['max_price'], price)
        stat['min_price'] = min(stat['min_price'], price)

        try:
            ts = datetime.fromisoformat(ts_str)
            if now - ts < timedelta(hours=24):
                recent_count_24h += 1
        except:
            pass

    result = {}
    for name, stat in stats.items():
        avg_price = round(stat['total_price'] / stat['count'], 2)
        result[name] = {
            'avg_price': avg_price,
            'count': stat['count'],
            'locations_count': len(stat['locations']),
            'max_price': stat['max_price'],
            'min_price': stat['min_price']
        }

    return jsonify({
        'success': True,
        'statistics': result,
        'recent_count_24h': recent_count_24h
    })

@app.route('/api/products')
def api_products():
    all_data = data_manager.get_latest_prices(limit=100000)
    product_map = {}

    for item in all_data:
        name = item.get('name')
        price = float(item.get('price_value') or 0)
        location = item.get('location')

        if not name or not price:
            continue

        if name not in product_map:
            product_map[name] = {
                'name': name,
                'latest_price': price,
                'avg_price': 0,
                'count': 0,
                'total_price': 0,
                'max_price': price,
                'min_price': price,
                'locations': set()
            }

        stat = product_map[name]
        stat['latest_price'] = price
        stat['count'] += 1
        stat['total_price'] += price
        stat['locations'].add(location)
        stat['max_price'] = max(stat['max_price'], price)
        stat['min_price'] = min(stat['min_price'], price)

    products = []
    for name, stat in product_map.items():
        avg_price = round(stat['total_price'] / stat['count'], 2)
        price_range = f"{stat['min_price']} - {stat['max_price']}"
        products.append({
            'name': name,
            'latest_price': stat['latest_price'],
            'avg_price': avg_price,
            'price_range': price_range,
            'locations_count': len(stat['locations']),
            'data_count': stat['count']
        })

    return jsonify({
        'success': True,
        'products': sorted(products, key=lambda x: x['data_count'], reverse=True)
    })

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(description='本地惠农网价格数据Web仪表板')
    parser.add_argument('--host', default='0.0.0.0', help='监听地址')
    parser.add_argument('--port', default=8080, type=int, help='监听端口')
    parser.add_argument('--debug', action='store_true', help='调试模式')

    args = parser.parse_args()

    print("=" * 60)
    print("本地惠农网农产品价格监控Web仪表板")
    print("=" * 60)
    print(f"虚拟机Redis地址: {VM_CONFIG['redis_host']}:{VM_CONFIG['redis_port']}")
    print(f"本地Web地址: http://localhost:{args.port}")
    print("=" * 60)

    app.run(
        host=args.host,
        port=args.port,
        debug=args.debug,
        threaded=True
    )
